package com.wsh.crawler.service.impl.parser;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.wsh.crawler.constant.LanguageEnum;
import com.wsh.crawler.constant.NewsSourceEnum;
import com.wsh.crawler.entity.News;
import com.wsh.crawler.utils.HttpClientUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class PremierLeagueParser extends AbstractNewsParser {

    private final static Logger LOGGER = LoggerFactory.getLogger(PremierLeagueParser.class);

    // 英超官方图片域名
    private final static String PREMIER_LEAGUE_IMAGE_DOMAIN = "https://resources.premierleague.pulselive.com";

    // 英超API接口
    private final static String PREMIER_LEAGUE_API = "https://footballapi.pulselive.com/content/PremierLeague/text/EN/?sort=timestamp%20desc&limit=20&offset=0&tagNames=News&fullObjectResponse=true";

    private final HttpClientUtil httpClientUtil;
    private final ObjectMapper objectMapper;

    public PremierLeagueParser(HttpClientUtil httpClientUtil) {
        super(NewsSourceEnum.PREMIER_LEAGUE.getName());
        this.httpClientUtil = httpClientUtil;
        this.objectMapper = new ObjectMapper();
    }

    @Override
    public List<String> parseArticleLinks(Document doc) {
        LOGGER.info("【英超解析】开始通过API解析新闻链接");

        List<String> links = new ArrayList<>();

        try {
            // 直接调用API接口
            String apiResponse = httpClientUtil.get(PREMIER_LEAGUE_API);

            if (apiResponse == null || apiResponse.isEmpty()) {
                LOGGER.error("【英超解析】API响应为空");
                return links;
            }

            LOGGER.info("【英超解析】API响应长度：{}", apiResponse.length());

            // 解析JSON响应
            JsonNode root = objectMapper.readTree(apiResponse);

            // 检查是否有content字段
            JsonNode content = root.get("content");
            if (content == null || !content.isArray()) {
                LOGGER.error("【英超解析】API响应中未找到content数组");
                return links;
            }

            LOGGER.info("【英超解析】找到 {} 个新闻项", content.size());

            // 遍历新闻项
            for (JsonNode item : content) {
                try {
                    // 提取新闻ID
                    JsonNode idNode = item.get("id");
                    if (idNode != null) {
                        String newsId = idNode.asText();
                        String newsUrl = "https://www.premierleague.com/news/" + newsId;
                        links.add(newsUrl);

                        // 提取标题用于调试
                        String title = "无标题";
                        JsonNode titleNode = item.get("title");
                        if (titleNode != null) {
                            title = titleNode.asText();
                        }

                        LOGGER.info("【英超解析】新闻：{} -> {}", title, newsUrl);
                    }
                } catch (Exception e) {
                    LOGGER.warn("【英超解析】解析单个新闻项失败", e);
                }
            }

            LOGGER.info("【英超解析】共解析到 {} 个新闻链接", links.size());

        } catch (Exception e) {
            LOGGER.error("【英超解析】API解析失败", e);
        }

        return links.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public News parseArticle(Document doc, String url) {
        LOGGER.info("【英超解析】正在解析{}的文章", url);

        News article = new News();
        article.setSource(NewsSourceEnum.PREMIER_LEAGUE.getName());
        article.setOriginalUrl(url);
        article.setCrawlTime(new Date());

        try {
            // 解析标题
            Element titleElement = doc.selectFirst("h1.page-header__name");
            if (titleElement != null) {
                article.setTitle(titleElement.text().trim());
            }

            if (article.getTitle() == null || article.getTitle().isEmpty()) {
                titleElement = doc.selectFirst("h1, .article-header__title, .hero__title");
                if (titleElement != null) {
                    article.setTitle(titleElement.text().trim());
                }
            }

            // 解析内容
            Element contentElement = doc.selectFirst(
                    ".article__content, " +
                            ".article__body, " +
                            ".page-content, " +
                            ".story-body, " +
                            ".article-body, " +
                            "[data-testid='article-content']"
            );

            if (contentElement != null) {
                LOGGER.info("【英超解析】找到内容区域：{}", contentElement.className());
                String content = contentElement.text().trim();
                article.setContent(content);
                LOGGER.info("【英超解析】内容长度：{}", content.length());
            } else {
                LOGGER.warn("【英超解析】未找到内容区域，尝试备用方法");

                // 备用方法：提取所有段落
                Elements contentElements = doc.select("p, div.article-text");
                StringBuilder contentBuilder = new StringBuilder();

                for (Element element : contentElements) {
                    String text = element.text().trim();

                    // 过滤掉导航、广告等无关内容
                    String className = element.className().toLowerCase();
                    if (className.contains("nav") || className.contains("menu") ||
                            className.contains("ad") || className.contains("footer") ||
                            className.contains("header") || className.contains("sidebar")) {
                        continue;
                    }

                    if (text.length() > 30) { // 过滤太短的文本
                        contentBuilder.append(text).append("\n\n");
                    }
                }

                if (contentBuilder.length() > 0) {
                    article.setContent(contentBuilder.toString().trim());
                    LOGGER.info("【英超解析】通过备用方法获取内容，长度：{}", article.getContent().length());
                }
            }

            // 提取图片和视频
            article.setImageUrls(extractImageUrls(doc));
            article.setVideoUrls(extractVideoUrls(doc));
            article.setLanguage(LanguageEnum.EN.getValue());

            // 提取封面图片
            article.setCoverUrl(extractCoverImage(doc, article.getImageUrls()));

            LOGGER.info("【英超解析】文章解析完成：{}", article.getTitle());

        } catch (Exception e) {
            LOGGER.error("【英超解析】解析文章内容失败：{}", url, e);
            return null;
        }

        return article;
    }

    /**
     * 提取封面图片
     */
    @Override
    public String extractCoverImage(Document doc, List<String> otherImageUrls) {
        LOGGER.info("【英超解析】开始提取封面图片");

        // 1. 优先从meta标签获取
        String coverUrl = extractCoverFromMeta(doc);
        if (isValidImageUrl(coverUrl)) {
            LOGGER.info("【英超解析】从meta标签获取封面：{}", coverUrl);
            return coverUrl;
        }

        // 2. 从页面头部的主图获取
        Element heroImage = doc.selectFirst(".page-header__image img, .hero__image img, .article-header__image img");
        if (heroImage != null) {
            String src = heroImage.attr("abs:src");
            if (isValidImageUrl(src)) {
                LOGGER.info("【英超解析】从页面头部获取封面：{}", src);
                return src;
            }
        }

        // 3. 从英超官方图片域名中选择
        if (CollectionUtils.isNotEmpty(otherImageUrls)) {
            for (String imageUrl : otherImageUrls) {
                if (imageUrl.contains(PREMIER_LEAGUE_IMAGE_DOMAIN)) {
                    LOGGER.info("【英超解析】从图片内容选一张作为封面：{}", imageUrl);
                    return imageUrl;
                }
            }

            // 4. 如果没有官方图片，选择第一张有效图片
            for (String imageUrl : otherImageUrls) {
                if (isValidImageUrl(imageUrl)) {
                    LOGGER.info("【英超解析】选择第一张有效图片作为封面：{}", imageUrl);
                    return imageUrl;
                }
            }
        }

        LOGGER.warn("【英超解析】未找到合适的封面图片");
        return null;
    }

    /**
     * 从meta标签提取封面图片
     */
    private String extractCoverFromMeta(Document doc) {
        // Open Graph标签
        Element ogImage = doc.selectFirst("meta[property=og:image]");
        if (ogImage != null) {
            String content = ogImage.attr("content");
            if (!content.isEmpty()) {
                return content;
            }
        }

        // Twitter卡片标签
        Element twitterImage = doc.selectFirst("meta[name=twitter:image], meta[property=twitter:image]");
        if (twitterImage != null) {
            String content = twitterImage.attr("content");
            if (!content.isEmpty()) {
                return content;
            }
        }

        // 其他可能的meta标签
        Element metaImage = doc.selectFirst("meta[name=image], meta[property=image]");
        if (metaImage != null) {
            String content = metaImage.attr("content");
            if (!content.isEmpty()) {
                return content;
            }
        }

        return null;
    }

    /**
     * 验证是否为有效的图片URL
     */
    private boolean isValidImageUrl(String url) {
        if (url == null || url.trim().isEmpty()) {
            return false;
        }

        String lowerUrl = url.toLowerCase();
        return lowerUrl.contains("jpg") || lowerUrl.contains("jpeg") ||
                lowerUrl.contains("png") || lowerUrl.contains("gif") ||
                lowerUrl.contains("webp") || lowerUrl.contains("svg") ||
                lowerUrl.startsWith("data:image/");
    }

    @Override
    protected List<String> extractImageUrls(Document doc) {
        List<String> imageUrls = new ArrayList<>();

        // 从文章内容中提取图片
        doc.select("img[src]").forEach(img -> {
            String src = img.attr("abs:src");
            if (!src.isEmpty() && !src.contains("placeholder") && !src.contains("loading")) {
                imageUrls.add(src);
            }
        });

        // 特别处理英超官网的picture标签内的图片
        doc.select("picture img[src]").forEach(img -> {
            String src = img.attr("abs:src");
            if (!src.isEmpty() && !src.contains("placeholder") && !src.contains("loading")) {
                imageUrls.add(src);
            }
        });

        // 从srcset属性中提取高质量图片
        doc.select("img[srcset]").forEach(img -> {
            String srcset = img.attr("srcset");
            if (!srcset.isEmpty()) {
                // 提取srcset中的最高质量图片
                String[] sources = srcset.split(",");
                for (String source : sources) {
                    String url = source.trim().split("\\s+")[0];
                    if (!url.isEmpty() && isValidImageUrl(url)) {
                        imageUrls.add(url);
                    }
                }
            }
        });

        return imageUrls.stream().distinct().collect(Collectors.toList());
    }

    @Override
    protected List<String> extractVideoUrls(Document doc) {
        List<String> videoUrls = new ArrayList<>();

        // 查找video标签
        doc.select("video source").forEach(video -> {
            String url = video.attr("abs:src");
            if (!url.isEmpty()) {
                videoUrls.add(url);
            }
        });

        // 查找iframe嵌入的视频
        doc.select("iframe[src*=youtube], iframe[src*=vimeo], iframe[src*=dailymotion], iframe[src*=premierleague]").forEach(iframe -> {
            String url = iframe.attr("abs:src");
            if (!url.isEmpty()) {
                videoUrls.add(url);
            }
        });

        // 英超官网可能的视频容器
        doc.select(".video-container iframe, .video-player iframe").forEach(iframe -> {
            String url = iframe.attr("abs:src");
            if (!url.isEmpty()) {
                videoUrls.add(url);
            }
        });

        return videoUrls.stream().distinct().collect(Collectors.toList());
    }
}